From 447bf55e45b00426ed908b1b1035f472c2466956 Mon Sep 17 00:00:00 2001 From: Alessandro Bono Date: Fri, 23 Sep 2016 21:08:11 +0200 Subject: [PATCH] panel: Add transparency when free-floating The solid black top bar we currently use works well for maximized or tiled windows, as it puts focus on the application content by blending into the monitor bezel. However it also visually reduces the screen space, which is particularly noticeable when no window is located nearby. Having the top bar blend with the background is a better option in that case, so track window positions and add some transparency when the top bar is free-floating. https://bugzilla.gnome.org/show_bug.cgi?id=747163 --- data/theme/gnome-shell-high-contrast.css | 35 +++++++++++++++-- data/theme/gnome-shell.css | 35 +++++++++++++++-- js/ui/panel.js | 49 ++++++++++++++++++++++++ 3 files changed, 111 insertions(+), 8 deletions(-) diff --git a/data/theme/gnome-shell-high-contrast.css b/data/theme/gnome-shell-high-contrast.css index b899b5433..30c11e2fb 100644 --- a/data/theme/gnome-shell-high-contrast.css +++ b/data/theme/gnome-shell-high-contrast.css @@ -669,7 +669,9 @@ StScrollBar { /* TOP BAR */ #panel { - background-color: black; + background-color: rgba(0, 0, 0, 0.2); + /* transition from solid to transparent */ + transition-duration: 500ms; font-weight: bold; height: 1.86em; } #panel.unlock-screen, #panel.login-screen, #panel.lock-screen { @@ -678,7 +680,7 @@ StScrollBar { spacing: 4px; } #panel .panel-corner { -panel-corner-radius: 6px; - -panel-corner-background-color: black; + -panel-corner-background-color: rgba(0, 0, 0, 0.2); -panel-corner-border-width: 2px; -panel-corner-border-color: transparent; } #panel .panel-corner:active, #panel .panel-corner:overview, #panel .panel-corner:focus { @@ -691,14 +693,24 @@ StScrollBar { -natural-hpadding: 12px; -minimum-hpadding: 6px; font-weight: bold; - color: #ccc; + color: #eee; + text-shadow: 0px 0px 2px rgba(0, 0, 0, 0.9); transition-duration: 100ms; } #panel .panel-button .app-menu-icon { -st-icon-style: symbolic; margin-left: 4px; margin-right: 4px; } + #panel .panel-button .system-status-icon, + #panel .panel-button .app-menu-icon > StIcon, + #panel .panel-button .popup-menu-arrow { + icon-shadow: 0px 0px 2px rgba(0, 0, 0, 0.9); } #panel .panel-button:hover { - color: white; } + color: white; + text-shadow: 0px 0px 8px black; } + #panel .panel-button:hover .system-status-icon, + #panel .panel-button:hover .app-menu-icon > StIcon, + #panel .panel-button:hover .popup-menu-arrow { + icon-shadow: 0px 0px 8px black; } #panel .panel-button:active, #panel .panel-button:overview, #panel .panel-button:focus, #panel .panel-button:checked { background-color: rgba(0, 0, 0, 0.01); box-shadow: inset 0 -2px 0px #256ab1; @@ -719,6 +731,21 @@ StScrollBar { spacing: 0; } #panel .screencast-indicator { color: #f57900; } + #panel.solid { + background-color: black; + /* transition from transparent to solid */ + transition-duration: 300ms; } + #panel.solid .panel-corner { + -panel-corner-background-color: black; } + #panel.solid .panel-button { + color: #ccc; + text-shadow: none; } + #panel.solid .panel-button:hover { + color: white; } + #panel.solid .system-status-icon, + #panel.solid .app-menu-icon > StIcon, + #panel.solid .popup-menu-arrow { + icon-shadow: none; } #calendarArea { padding: 0.75em 1.0em; } diff --git a/data/theme/gnome-shell.css b/data/theme/gnome-shell.css index 3896c99be..d9bf7a1e7 100644 --- a/data/theme/gnome-shell.css +++ b/data/theme/gnome-shell.css @@ -669,7 +669,9 @@ StScrollBar { /* TOP BAR */ #panel { - background-color: black; + background-color: rgba(0, 0, 0, 0.2); + /* transition from solid to transparent */ + transition-duration: 500ms; font-weight: bold; height: 1.86em; } #panel.unlock-screen, #panel.login-screen, #panel.lock-screen { @@ -678,7 +680,7 @@ StScrollBar { spacing: 4px; } #panel .panel-corner { -panel-corner-radius: 6px; - -panel-corner-background-color: black; + -panel-corner-background-color: rgba(0, 0, 0, 0.2); -panel-corner-border-width: 2px; -panel-corner-border-color: transparent; } #panel .panel-corner:active, #panel .panel-corner:overview, #panel .panel-corner:focus { @@ -691,14 +693,24 @@ StScrollBar { -natural-hpadding: 12px; -minimum-hpadding: 6px; font-weight: bold; - color: #ccc; + color: #eee; + text-shadow: 0px 0px 2px rgba(0, 0, 0, 0.9); transition-duration: 100ms; } #panel .panel-button .app-menu-icon { -st-icon-style: symbolic; margin-left: 4px; margin-right: 4px; } + #panel .panel-button .system-status-icon, + #panel .panel-button .app-menu-icon > StIcon, + #panel .panel-button .popup-menu-arrow { + icon-shadow: 0px 0px 2px rgba(0, 0, 0, 0.9); } #panel .panel-button:hover { - color: white; } + color: white; + text-shadow: 0px 0px 8px black; } + #panel .panel-button:hover .system-status-icon, + #panel .panel-button:hover .app-menu-icon > StIcon, + #panel .panel-button:hover .popup-menu-arrow { + icon-shadow: 0px 0px 8px black; } #panel .panel-button:active, #panel .panel-button:overview, #panel .panel-button:focus, #panel .panel-button:checked { background-color: rgba(0, 0, 0, 0.01); box-shadow: inset 0 -2px 0px #256ab1; @@ -719,6 +731,21 @@ StScrollBar { spacing: 0; } #panel .screencast-indicator { color: #f57900; } + #panel.solid { + background-color: black; + /* transition from transparent to solid */ + transition-duration: 300ms; } + #panel.solid .panel-corner { + -panel-corner-background-color: black; } + #panel.solid .panel-button { + color: #ccc; + text-shadow: none; } + #panel.solid .panel-button:hover { + color: white; } + #panel.solid .system-status-icon, + #panel.solid .app-menu-icon > StIcon, + #panel.solid .popup-menu-arrow { + icon-shadow: none; } #calendarArea { padding: 0.75em 1.0em; } diff --git a/js/ui/panel.js b/js/ui/panel.js index fe3fc392f..a7d63d23c 100644 --- a/js/ui/panel.js +++ b/js/ui/panel.js @@ -801,9 +801,11 @@ const Panel = new Lang.Class({ Main.overview.connect('showing', Lang.bind(this, function () { this.actor.add_style_pseudo_class('overview'); + this._updateSolidStyle(); })); Main.overview.connect('hiding', Lang.bind(this, function () { this.actor.remove_style_pseudo_class('overview'); + this._updateSolidStyle(); })); Main.layoutManager.panelBox.add(this.actor); @@ -811,9 +813,26 @@ const Panel = new Lang.Class({ { sortGroup: CtrlAltTab.SortGroup.TOP }); Main.sessionMode.connect('updated', Lang.bind(this, this._updatePanel)); + + this._trackedWindows = new Map(); + global.window_group.connect('actor-added', Lang.bind(this, this._onWindowActorAdded)); + global.window_group.connect('actor-removed', Lang.bind(this, this._onWindowActorRemoved)); + global.window_manager.connect('switch-workspace', Lang.bind(this, this._updateSolidStyle)); + this._updatePanel(); }, + _onWindowActorAdded: function(container, metaWindowActor) { + let signalId = metaWindowActor.connect('allocation-changed', Lang.bind(this, this._updateSolidStyle)); + this._trackedWindows.set(metaWindowActor, signalId); + }, + + _onWindowActorRemoved: function(container, metaWindowActor) { + metaWindowActor.disconnect(this._trackedWindows.get(metaWindowActor)); + this._trackedWindows.delete(metaWindowActor); + this._updateSolidStyle(); + }, + _getPreferredWidth: function(actor, forHeight, alloc) { alloc.min_size = -1; alloc.natural_size = Main.layoutManager.primaryMonitor.width; @@ -1012,6 +1031,36 @@ const Panel = new Lang.Class({ } }, + _updateSolidStyle: function() { + if (this.actor.has_style_pseudo_class('overview') || !Main.sessionMode.hasWindows) { + this._removeStyleClassName('solid'); + return; + } + + /* Get all the windows in the active workspace that are in the primary monitor and visible */ + let activeWorkspace = global.screen.get_active_workspace(); + let windows = activeWorkspace.list_windows().filter(function(metaWindow) { + return metaWindow.is_on_primary_monitor() && + metaWindow.showing_on_its_workspace() && + metaWindow.get_window_type() != Meta.WindowType.DESKTOP; + }); + + /* Check if at least one window is near enough to the panel */ + let [, panelTop] = this.actor.get_transformed_position(); + let panelBottom = panelTop + this.actor.get_height(); + let scale = St.ThemeContext.get_for_stage(global.stage).scale_factor; + let isNearEnough = windows.some(Lang.bind(this, function(metaWindow) { + let verticalPosition = metaWindow.get_frame_rect().y; + return verticalPosition < panelBottom + 5 * scale; + })); + + if (isNearEnough) + this._addStyleClassName('solid'); + else + this._removeStyleClassName('solid'); + + }, + _hideIndicators: function() { for (let role in PANEL_ITEM_IMPLEMENTATIONS) { let indicator = this.statusArea[role]; -- 2.39.5